package com.campus.counseling.service.impl;

import com.campus.counseling.model.vo.SystemLoadVO;
import com.campus.counseling.service.SystemMonitorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.text.DecimalFormat;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class SystemMonitorServiceImpl implements SystemMonitorService {
    
    private final SystemInfo systemInfo;
    private final DecimalFormat decimalFormat;
    
    public SystemMonitorServiceImpl() {
        this.systemInfo = new SystemInfo();
        this.decimalFormat = new DecimalFormat("#.##");
    }
    
    @Override
    public SystemLoadVO getSystemLoad() {
        SystemLoadVO systemLoad = new SystemLoadVO();
        try {
            HardwareAbstractionLayer hardware = systemInfo.getHardware();
            OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
            
            // 获取CPU使用率
            double cpuUsage = getCpuUsage(hardware.getProcessor());
            systemLoad.setCpuUsage(Double.valueOf(decimalFormat.format(cpuUsage)));
            
            // 获取内存信息
            GlobalMemory memory = hardware.getMemory();
            long totalMemory = memory.getTotal() / 1024 / 1024; // 转换为MB
            long usedMemory = (memory.getTotal() - memory.getAvailable()) / 1024 / 1024;
            double memoryUsage = usedMemory * 100.0 / totalMemory;
            
            systemLoad.setTotalMemory(totalMemory);
            systemLoad.setUsedMemory(usedMemory);
            systemLoad.setFreeMemory(totalMemory - usedMemory);
            systemLoad.setMemoryUsage(Double.valueOf(decimalFormat.format(memoryUsage)));
            
            // 获取磁盘信息
            FileSystem fileSystem = operatingSystem.getFileSystem();
            List<OSFileStore> fileStores = fileSystem.getFileStores();
            long totalDisk = 0;
            long usedDisk = 0;
            
            for (OSFileStore store : fileStores) {
                totalDisk += store.getTotalSpace() / 1024 / 1024 / 1024; // 转换为GB
                usedDisk += (store.getTotalSpace() - store.getUsableSpace()) / 1024 / 1024 / 1024;
            }
            
            double diskUsage = usedDisk * 100.0 / totalDisk;
            systemLoad.setTotalDisk(totalDisk);
            systemLoad.setUsedDisk(usedDisk);
            systemLoad.setFreeDisk(totalDisk - usedDisk);
            systemLoad.setDiskUsage(Double.valueOf(decimalFormat.format(diskUsage)));
            
            // 获取线程信息
            ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
            systemLoad.setThreadCount(threadBean.getThreadCount());
            
            // 设置系统状态
            determineSystemStatus(systemLoad);
            
        } catch (Exception e) {
            log.error("获取系统负载信息失败", e);
            systemLoad.setStatus("ERROR");
            systemLoad.setMessage("系统监控服务异常");
        }
        
        return systemLoad;
    }
    
    @Override
    public String getSystemStatus() {
        SystemLoadVO load = getSystemLoad();
        return load.getStatus() + " - " + load.getMessage();
    }
    
    private double getCpuUsage(CentralProcessor processor) {
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        long[] ticks = processor.getSystemCpuLoadTicks();
        
        long nice = ticks[CentralProcessor.TickType.NICE.getIndex()]
                - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
        long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()]
                - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
        long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()]
                - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
        long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()]
                - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
        long system = ticks[CentralProcessor.TickType.SYSTEM.getIndex()]
                - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
        long user = ticks[CentralProcessor.TickType.USER.getIndex()]
                - prevTicks[CentralProcessor.TickType.USER.getIndex()];
        long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()]
                - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
        long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()]
                - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
        
        long totalCpu = user + nice + system + idle + iowait + irq + softirq + steal;
        return (totalCpu - idle) * 100.0 / totalCpu;
    }
    
    private void determineSystemStatus(SystemLoadVO systemLoad) {
        StringBuilder message = new StringBuilder();
        String status = "NORMAL";
        
        // CPU负载检查
        if (systemLoad.getCpuUsage() > 90) {
            status = "DANGER";
            message.append("CPU使用率过高; ");
        } else if (systemLoad.getCpuUsage() > 70) {
            status = "WARNING";
            message.append("CPU使用率较高; ");
        }
        
        // 内存使用检查
        if (systemLoad.getMemoryUsage() > 90) {
            status = "DANGER";
            message.append("内存使用率过高; ");
        } else if (systemLoad.getMemoryUsage() > 70) {
            status = "WARNING";
            message.append("内存使用率较高; ");
        }
        
        // 磁盘使用检查
        if (systemLoad.getDiskUsage() > 90) {
            status = "DANGER";
            message.append("磁盘使用率过高; ");
        } else if (systemLoad.getDiskUsage() > 70) {
            status = "WARNING";
            message.append("磁盘使用率较高; ");
        }
        
        if (message.length() == 0) {
            message.append("系统运行正常");
        }
        
        systemLoad.setStatus(status);
        systemLoad.setMessage(message.toString());
    }
} 